<html><head>
    <title>Image Gauge</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" href="{{ STATIC_URL }}css/webgl.css" type="text/css">
    <script src="{{ STATIC_URL }}jsp/gl-matrix.js" type="text/javascript"></script>  
    <script src="{{ STATIC_URL }}jsp/sylvester.js" type="text/javascript"></script>
    <script src="{{ STATIC_URL }}jsp/glUtils.js" type="text/javascript"></script> 
    
    
    <script tyep = "text/javascript">
		
	var STATIC_URL = "{{ STATIC_URL }}";
		
	var canvas;
	var gl;
	var midImageFile = STATIC_URL + "images/sphere/mid.png" 
	
	var webglImageShader = null;
	var gaugeShader = null;
	
	
	var gaugeGroundTruth = {{ positionNormals }};
	/*
	 [
			[354, 171, 30, 30, 75, 191],
			[626, 162, 45, 43, 67, 53],
			[627, 381, 47, 46, 187, 50],
			[369, 370, 26, 25, 181, 181]
			];
			*/
	var test_gaugeIndex = 1;
	var depthResize =  {{ depthResize }};
	var depthOffset = {{ depthOffset }};
	var focalLength = {{ focalLength }} ;
	var sensorWidth = {{ sensorWidth }};
	var sensorHeight = 18;  
	
	
	function handleMouseDown()
	{
		test_gaugeIndex += 1;
		test_gaugeIndex %= gaugeGroundTruth.length;
	}
	function handleMouseUp()
	{
	}
	function handleMouseMove()
	{
		
	}
	
	function start() 
	{
	  canvas = document.getElementById("glcanvas");
	  
	  sensorHeight = sensorWidth * canvas.height / canvas.width;

	  initWebGL();      // Initialize the GL context	  
	  
	  // Only continue if WebGL is available and working
	  canvas.onmousedown = handleMouseDown;
	  document.onmouseup = handleMouseUp;
	  document.onmousemove = handleMouseMove;
	  
	  if (gl) 
	  {
		gl.clearColor(0.0, 0.0, 0.0, 1.0);  // Clear to black, fully opaque
		gl.clearDepth(1.0);                 // Clear everything
		gl.enable(gl.DEPTH_TEST);           // Enable depth testing
		gl.depthFunc(gl.LEQUAL);            // Near things obscure far things
		
		// Initialize the shaders; this is where all the lighting for the
		// vertices and so forth is established.
		
		webglImageShader = new WebGLImageShader();
		gaugeShader = new WebGLGaugeShader();
		
		// Here's where we call the routine that builds all the objects
		// we'll be drawing.
	
		webglImageShader.initBuffers(gl);	
		gaugeShader.initGaugeBuffers(gl);
		
		webglImageShader.initShaders(gl, "shader-vs-image", "shader-fs-image");
		gaugeShader.initShaders(gl, "shader-vs-gauge", "shader-fs-gauge");
		
		// Next, load and set up the textures we'll be using.
		
		//cubetexture.png random_obj_1/left/Image0001.png  desktop.png
		
		// Set up to draw the scene periodically.
		initTextures(midImageFile);
		
		setInterval(drawScene, 15);
	  }
	  else
	  {
		  alert("can't initWebGL. Please enable WegGL in your browser.");
	  }
	}
	
	
	//
	// initWebGL
	//
	// Initialize WebGL, returning the GL context or null if
	// WebGL isn't available or could not be initialized.
	//
	function initWebGL()
	{
	  gl = null;
	  
	  try {
		gl = canvas.getContext("experimental-webgl");
	  }
	  catch(e) {
	  }
	  
	  // If we don't have a GL context, give up now
	  
	  if (!gl) {
		alert("Unable to initialize WebGL. Your browser may not support it.");
	  }
	}	
	
	
	function drawScene()
	{
		webglImageShader.drawImage(gl);
		drawGauge();
	}
	
	function calcPosition(x, y, depth255)
	{		
		var h = canvas.height;
		var w = canvas.width;
		var px = x, py = y, pz;
		var pz = depth255/255.0 * depthResize - depthOffset;
		var ratio = w/sensorWidth;
		var fc = focalLength * ratio;
		
		//reverse y since y = 0 in left top corner of windows
		y = h - y;
		
		var dir = vec3.fromValues(x - w/2, y - h/2, fc);		
		vec3.normalize(dir, dir);		
		var scale = pz/dir[2];
		vec3.scale(dir, dir, scale);
		
		dir[2] = - dir[2];		
		return dir;	
	}
	
	//nx, ny,
	function calcRotation(nr, ng, nb)
	{	
		
		//pixel to normal
		var nx, ny, nz;
		nx = nr/255.0;
		ny = ng/255.0;
		nz = nb/255.0;
		
		nx = (nx - 0.5) * 2.0;
		ny = (ny - 0.5) * 2.0;
		nz = (nz - 0.5) * 2.0;		
		
		var n = vec3.fromValues(-nx, -ny, nz);
		vec3.normalize(n, n);		
		
		//normal to rotation matrix		
		nx = n[0];
		ny = n[1];
		nz = n[2];
		var theta = Math.PI - Math.acos(nz);		
		var phi = Math.atan2(ny, nx);
		
		
		var rY = mat4.create();
		var rZ = mat4.create();
		var rMatrix = mat4.create();
		mat4.identity(rY);
		mat4.identity(rZ);
				
        mat4.rotateY(rY, rY, theta);
        mat4.rotateZ(rZ, rZ, phi);
        mat4.multiply(rMatrix, rZ, rY);  //order
        return rMatrix;        	
	}
	
	
	
	function drawGauge()
	{
		// Clear the canvas before we start drawing on it.

	  gl.clear(gl.DEPTH_BUFFER_BIT);
	  gl.useProgram(gaugeShader.shaderProgram);
	  
	  // Establish the perspective with which we want to view the
	  // scene. Our field of view is 45 degrees, with a width/height
	  // ratio of 640:480, and we only want to see objects between 0.1 units
	  // and 100 units away from the camera.
	  
	  var perspectiveMatrix = mat4.create();
	  var modelMatrix = mat4.create();
	  var mvMatrix = mat4.create();
	  mat4.identity(perspectiveMatrix);
	  mat4.identity(modelMatrix);
	  mat4.identity(mvMatrix);
	  
	  //28.83 = atan(9.0/35.0)*2
	  var fovy = Math.atan(sensorHeight/2/focalLength) * 2;
	  //perspectiveMatrix = makePerspective(angle, canvas.width/canvas.height, 0.1, 100.0);
	  mat4.perspective(perspectiveMatrix, fovy, canvas.width/canvas.height, 0.1, 100.0);
	  
	 
	   
	  // Now move the drawing position a bit to where we want to start
	  // drawing the cube.	
	  //rotate the object
	  var nb = gaugeGroundTruth[test_gaugeIndex][3];
	  var ng = gaugeGroundTruth[test_gaugeIndex][4];
	  var nr = gaugeGroundTruth[test_gaugeIndex][5];	 	 	 
	  var rotateMatrix = calcRotation(nr, ng, nb);
	  
	  
	  //move to current position  
	  var x = gaugeGroundTruth[test_gaugeIndex][0];
	  var y = gaugeGroundTruth[test_gaugeIndex][1];
	  var depth255 = gaugeGroundTruth[test_gaugeIndex][2];
	  var pos = calcPosition(x, y, depth255)	  
	  
	  var translateMatrix = mat4.create();
	  mat4.identity(translateMatrix, translateMatrix);
	  mat4.translate(translateMatrix, translateMatrix, pos);
	  
	  //mat4.multiply(mvMatrix, rotateMatrix, translateMatrix);
	  mat4.multiply(mvMatrix, translateMatrix, rotateMatrix); 
	  
	  var viewMatrix = mat4.create();
	  var eye    = vec3.fromValues(0, 0, 0);
	  var center = vec3.fromValues(0, 0, -10);
	  var up = vec3.fromValues(0, 1, 0);
	  mat4.lookAt(viewMatrix, eye, center, up);
	  
	  mat4.multiply(mvMatrix, viewMatrix, mvMatrix);	  
	
	  
	  setMatrixUniforms(gaugeShader.shaderProgram, perspectiveMatrix, mvMatrix);	
	  //draw torus
	  gl.bindBuffer(gl.ARRAY_BUFFER, gaugeShader.verticesBuffer);
	  gl.vertexAttribPointer(gaugeShader.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);	   
	  gl.drawArrays(gl.TRIANGLE_STRIP, 0, (72+2)*2);
	  
	  //draw stick
	  gl.bindBuffer(gl.ARRAY_BUFFER, gaugeShader.stickVerticesBuffer);
	  gl.vertexAttribPointer(gaugeShader.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);	   
	  gl.drawArrays(gl.TRIANGLE_STRIP, 0, (72+2)*2);	 
	}	
	
	function initTextures(imageName)
	{
		webglImageShader.imageTexture = gl.createTexture();
		webglImageShader.image = new Image();
		webglImageShader.image.onload = function()
		{
			handleTextureLoaded(webglImageShader.image, webglImageShader.imageTexture);
		}  //set callback function
		webglImageShader.image.src = imageName;		
	}
	
	function handleTextureLoaded(image, texture)
	{
		gl.bindTexture(gl.TEXTURE_2D, texture);  //set current texture
		
		//set the parameters so we can render any size image.
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
		
		gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);		
		gl.bindTexture(gl.TEXTURE_2D, null); //set current texture null	
	} 	
    </script>
    
    <script src="{{ STATIC_URL }}jsp/imageShaderUtils.js" type="text/javascript"></script>
    <script src="{{ STATIC_URL }}jsp/gaugeShaderUtils.js" type="text/javascript"></script>
    <script src="{{ STATIC_URL }}jsp/matrixUtils.js" type="text/javascript"></script>   
    
    <!-- Image Vertex shader program -->    
    <script id="shader-vs-image" type="x-shader/x-vertex">
	  //uniform: not change value
	  //attribute: in vertex shader
	  //varying: from vertex to fragment
      attribute vec2 a_position;
      attribute vec2 a_texCoord;
      varying vec2 v_texCoord;
      uniform vec2 u_resolution;    
      void main(void) {
		  vec2 zeroToOne = a_position /u_resolution;
		  vec2 zeroToTwo = zeroToOne * 2.0;
		  vec2 clipSpace = zeroToTwo - 1.0;		   
          gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
          v_texCoord = a_texCoord;
      }
    </script>
    
    <!-- Fragment shader program -->
    <script id="shader-fs-image" type="x-shader/x-fragment">
		precision mediump float;
		uniform sampler2D u_image;
		varying vec2 v_texCoord;
      
        void main(void)
        {
			gl_FragColor = texture2D(u_image, v_texCoord);
		}
    </script>
    
    <!-- Gauge Shader -->
    <!-- Vertex shader program -->
    
    <script id="shader-vs-gauge" type="x-shader/x-vertex">
      attribute vec3 aVertexPosition;
  //    attribute vec4 aVertexColor;
    
      uniform mat4 uMVMatrix;
      uniform mat4 uPMatrix;
      
	  varying lowp vec4 vColor;
    
      void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vColor = vec4(1.0, 0.0, 0.0, 1.0);
 //       vColor = aVertexColor;
      }
    </script>
    
    <!-- Fragment shader program -->
    <script id="shader-fs-gauge" type="x-shader/x-fragment">
    	varying lowp vec4 vColor;
    	
      void main(void) {
        gl_FragColor = vColor;
      }
    </script>
    
    
    
    
    
  </head>
  
  <body onload="start()">
    <canvas id="glcanvas" width="960" height="540">
      Your browser doesn't appear to support the HTML5 <code>&lt;canvas&gt;</code> element.
    </canvas>
  
</body></html>

